/*
	Stargate SENT for GarrysMod10
	Copyright (C) 2007  aVoN

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
-- FIXME: Todo - Rewrite this using "ANIM" like in "stargate_iris" sent.
ENT.Sequence = {};

--################# Pegasus gates - Dialling sequence @aVoN
-- ATTENTION: The dialling time takes exactly 7 seconds with my gates (dialled in fast mode). When you code your own gates, make them take 7 seconds too!
-- You can check a dialling sequence's length with adding "print_r(delay)" to end of the stargate_base's ENT:RunAction() function
function ENT.Sequence:Dial(inbound,fast,fail)
	local action = self:New();
	local add = 29.5; -- Delay, when it got dialled slowly by an SG1 gate.
	if(fast) then add = 0 end;
	--################# INBOUND DIALLING
	if(inbound) then
		add = add + 2.5; -- The delay is necessary because the diallin below takes about 4.5 seconds with a delay of 0.1 second between each light
		local rnd = {};
		for i=1,7 do
			math.randomseed(os.clock()+i); -- Increases randomness
			if(i == 4) then
				-- This delay must be a bit shorter!
				rnd[i] = math.random(11,13)/100;
				add = add + (0.1-rnd[i])*12;
			else
				rnd[i] = math.random(14,17)/100;
				add = add + (0.1-rnd[i])*4;
			end
		end
		action:Add({f=self.SetStatus,v={self,false,true,true},d=add}); -- The first true tells, "we are in use", but the last tells wire NOT to indicate us as "Active". Otherwise, on a slow dial-in, a gate becomes "Wire-Active" even if it's not currently dialling
		action:Add({f=self.SetStatus,v={self,false,true},d=0.2});
		action:Add({f=self.EmitSound,v={self.Entity,self.Sounds.Ring,90,math.random(98,103)},d=0.1}); -- Ring Sound
		action:Add({f=self.Fire,v={self.Entity,"SetBodyGroup",1},d=0.2}); -- Activate the mainlight
		-- We are doing exactly 36 steps, so we are adding this delay now in every step.
		--action:Add({f=self.Fire,v={self.Entity,"SetBodyGroup",1},d=0.5}); -- Activate the gate's inbound lights
		for i=1,4 do
			action:Add({f=self.RingLight,v={self,self.ChevronLocks[1] - 4 + i,true},d=rnd[1]});
		end
		-- Chevron 1-7
		for i=1,7 do
			-- Chevron activated
			local snd = self.Sounds.Inbound;
			if(i == 7) then snd = self.Sounds.LockInbound end;
			action:Add({f=self.SetWire,v={self,"Chevron",i},d=0}); -- Wire
			action:Add({f=self.EmitSound,v={self.Entity,snd,90,math.random(98,103)},d=0});
			action:Add({f=self.DHDSetChevron,v={self,i,0.05},d=0});
			action:Add({f=self.ActivateChevron,v={self,i,true,true},d=0});
			if(i == 7) then
				action:Add({f=self.RingLight,v={self,0},d=0.4}); -- Stop the spinning light - We don't need it anymore
			else
				-- Spinning light
				local chevron = self.ChevronLocks[i+1] - 4; -- The startindex!
				local rounds = 4;
				if(i == 3) then
					-- First of all, we need it to spin through more chevrons (might look ugly, i know)
					rounds = 12;
					chevron = self.ChevronLocks[8] - 4
				end
				for k=1,rounds do
					action:Add({f=self.RingLight,v={self,chevron+k,true},d=rnd[1+i]});
				end
			end
		end
	else
		--################# OUTBOUND DIALLING
		-- Random delay
		action:Add({f=self.SetStatus,v={self,false,true},d=add});
		action:Add({f=self.EmitSound,v={self.Entity,self.Sounds.Ring,90,math.random(98,103)},d=0}); -- Ring Sound
		local dir = 1; -- Direction, into the moving chevrons goes
		local rnd = {}; -- Random time-ammount by a call to make it more "unartificial"
		for i=1,5 do
			math.randomseed(os.clock()+i); -- Increases randomness
			rnd[i] = math.Round(math.random(50,125)/100);
		end
		rnd[6] = 0.8; rnd[7] = 1; -- These rounds have to be at this values - Always (they aren't random!)
		-- Time offsets
		local delta = (5.5 - (rnd[1]+rnd[2]+rnd[3]+rnd[4]+rnd[5]+rnd[6]))/6;
		for i=1,6 do
			rnd[i] = math.Round((rnd[i]+delta)*10)/10;
		end
		-- Start spinning
		local chev = self.ChevronLocks[1]-14*dir;
		for i=1,14 do
			chev = chev+dir;
			action:Add({f=self.RingLight,v={self,chev},d=0.05});
		end
		action:Add({f=self.RingLight,v={self,0},d=0});
		-- Chevron 1-7
		for i=1,7 do
			if(not (i == 7 and fail)) then
				-- Chevron activated
				local snd = self.Sounds.Chevron;
				if(i == 7) then snd = self.Sounds.Lock end;
				action:Add({f=self.SetWire,v={self,"Chevron",i},d=0}); -- Wire
				action:Add({f=self.EmitSound,v={self.Entity,snd,90,math.random(98,103)},d=0});
				action:Add({f=self.DHDSetChevron,v={self,i,0.05},d=0});
				action:Add({f=self.ActivateChevron,v={self,i,true},d=0.4});
				if(i == 7) then
					-- Delay correction, or the gate openes to fast or slow because of the random dialling times
					local correction = 5.5 - (rnd[1]+rnd[2]+rnd[3]+rnd[4]+rnd[5]+rnd[6]);
					action:Add({f=self.RingLight,v={self,0},d=0.4 + correction}); -- Stop the spinning light - We don't need it anymore
				else
					-- Spinning light
					dir = dir*(-1); -- Change the direction of the spinning
					local rounds = (rnd[i]*10-4)*2; -- Calculate the necessary rounds for each spin
					local chev = self.ChevronLocks[i+1]-rounds*dir;
					for i=1,rounds do
						chev = chev+dir;
						action:Add({f=self.RingLight,v={self,chev},d=0.05});
					end
					action:Add({f=self.RingLight,v={self,0},d=0}); -- Stop the light of the spinning wheel
				end
			else
				action:Add({f=self.SetWire,v={self,"Chevron",-7},d=0}); -- Tell Wire, we failed to lock!
			end
		end
	end
	if(not fail) then
		action:Add({f=self.DHDSetChevron,v={self,8},d=0}); -- Activate near DHDs
	end
	return action;
end
